﻿using System;
using System.Collections.Generic;

namespace NazTek.Extension.Clr4
{
    /// <summary>
    /// Extends generic List&lt;T&gt;
    /// </summary>
    /// <remarks></remarks>
    public static class GenericListExtension
    {
        /// <summary> 
        /// Converts a list of items to a list of a different type, e.g., from a base list instance to a subclass list instance
        /// </summary> 
        /// <typeparam name="TTargetType">Type of the source list items</typeparam> 
        /// <typeparam name="TDestinationType">Type of the destination list items</typeparam> 
        /// <param name="from">Source list</param> 
        /// <returns>List of TDestinationType items</returns> 
        /// <exception cref="MissingMethodException">Thrown when target type has no parameterless constructor</exception>
        /// <remarks>Target type must have a parameterless constructor, and it may be private</remarks> 
        /// <example>
        /// <code>
        /// // context
        /// internal class Person
        /// {
        ///     internal string Name { get; set; }
        ///     internal int Age { get; set; }
        ///     internal Person(string pName, int pAge)
        ///     {
        ///         this.Name = pName;
        ///         this.Age = pAge;
        ///     }
        /// }
        /// internal class Senior : Person
        /// {
        ///     private Senior() : base("Elderly", 100) { } // voids MissingMethodException
        ///     Senior(string pName, int pAge) : base(pName, pAge) 
        ///     {
        ///         if (pAge &lt; 65)
        ///             throw new Exception("too young");
        ///     }
        /// }
        /// List&lt;Person&gt; persons = new List&lt;Person&gt;();
        /// persons.Add(new Person("Bob", 75));
        /// persons.Add(new Person("Jane", 77));
        /// 
        /// // usage
        /// List&lt;Senior&gt; seniors = persons.ConvertTo&lt;Person, Senior&gt;();
        /// </code>
        /// </example>
        [Obsolete("This operation is covdered by the .Net 4.0 covariance and contravariance")]
        public static List<TDestinationType> ConvertTo<TTargetType, TDestinationType>(this List<TTargetType> from)
            where TTargetType : class
            where TDestinationType : class
        {
            List<TDestinationType> list = new List<TDestinationType>();
            foreach (TTargetType item in from)
            {
                object to = Activator.CreateInstance(typeof(TDestinationType), true);
                item.CopyTo(to);
                list.Add(to as TDestinationType);
            }
            return list;
        }
    }
}
